#include "stack.h"
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>

void STACKInit(void){
  void * a =  (STACK **) malloc (sizeof (STACK*) * STACK_SIZE);
  stack_top.top = a;
  stack_top.threshold = 0;
  stack_top.c_size = STACK_SIZE;
  stack_top.location = -1;
}

void STACKRestart(void){
  free(stack_top.top);
  stack_top.top = (STACK **) malloc (sizeof (STACK*) * STACK_SIZE);
  stack_top.threshold = 0;
  stack_top.c_size = STACK_SIZE;
  stack_top.location = -1;
  bzero(stack_top.top,sizeof (STACK*) * STACK_SIZE);
}

void STACKPush(void * thing)
{
  if (stack_top.c_size - 1 == stack_top.location)
    {
      stack_top.threshold = stack_top.c_size - (stack_top.c_size / 4);
      stack_top.c_size= stack_top.c_size + (stack_top.c_size / 2);
      stack_top.top = (STACK **) realloc
	(stack_top.top, sizeof (STACK *) * stack_top.c_size);
    }
  stack_top.top[++stack_top.location] = thing;
}

void * STACKPop()
{
  void * a = stack_top.top[stack_top.location--];
  if (stack_top.threshold &&
      stack_top.threshold  == stack_top.location)
    {
      stack_top.c_size= stack_top.c_size * 2 / 3;
      if( stack_top.c_size <= STACK_SIZE )\
	{stack_top.threshold = 0;
	  stack_top.c_size = STACK_SIZE;}
      else
	stack_top.threshold = (stack_top.c_size * 2 / 3)
	  - ((stack_top.c_size * 2 / 3) / 4);
      stack_top.top = (STACK *) realloc
	(stack_top.top, sizeof (STACK *) * stack_top.c_size);
    }
    return a;
}

void STACKDebug (void)
{
  int i;
  for (i=0;i < stack_top.location; i++)
    {
      printf("[STACK@%d]:", i);
      print(STACKSee(i));
    }
  printf("[STACKStat]:top=0x%x;local=%d;threshold=%d;c_size=%d\n",
	 stack_top.top,
	 stack_top.location,
	 stack_top.threshold,
	 stack_top.c_size);
}

